package main

import (
	"github.com/coredns/caddy"
	"github.com/coredns/coredns/core/dnsserver"
	"github.com/coredns/coredns/plugin"
	clog "github.com/coredns/coredns/plugin/pkg/log"
	"strconv"
	"time"
)

var log = clog.NewWithPlugin("itdns")

const (
	defaultTtl                = 360
	defaultMaxLifeTime        = 1 * time.Minute
	defaultMaxOpenConnections = 10
	defaultMaxIdleConnections = 10
	defaultZoneUpdateTime     = 10 * time.Minute
)

//var (
//	open *sql.DB
//)

func init() {
	log.Info("注册组件", Name)

	//caddy.RegisterPlugin(Name, caddy.Plugin{
	//    ServerType: Name,
	//    Action:     setup,
	//})

	itDns := ItDns{
		TablePrefix: "it_dns_",
		Ttl:         300,
		Dsn:         "./it-dns.db",
	}

	if err := itDns.init(); err != nil {

		log.Error("初始化错误:", err)

		return
	}

	dnsserver.Directives = append(dnsserver.Directives, Name)

	log.Info("=Directives=>", dnsserver.Directives)

	plugin.Register(Name, itDns.setup)
}

func (itDns *ItDns) init() error {

	db, err := itDns.open()
	if err != nil {
		return err
	}

	err = db.Ping()
	if err != nil {
		return err
	}
	defer itDns.close(db)

	itDns.tableName = itDns.TablePrefix + "records"

	go itDns.webSrv()

	return nil
}

func (itDns *ItDns) setup(c *caddy.Controller) error {

	log.Info("执行setup")

	err := itDns.hostsParse(c)
	if err != nil {
		return plugin.Error("sqlite3", err)
	}

	dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler {
		itDns.Next = next
		return itDns
	})

	return nil
}

func (itDns *ItDns) hostsParse(c *caddy.Controller) error {
	log.Info("执行 hostsParse")
	var err error

	c.Next()
	if c.NextBlock() {
		for {
			switch c.Val() {
			case "dsn":
				if !c.NextArg() {
					return c.ArgErr()
				}
				itDns.Dsn = c.Val()
			case "table_prefix":
				if !c.NextArg() {
					return c.ArgErr()
				}
				itDns.TablePrefix = c.Val()
			case "max_lifetime":
				if !c.NextArg() {
					return c.ArgErr()
				}
				var val time.Duration
				val, err = time.ParseDuration(c.Val())
				if err != nil {
					val = defaultMaxLifeTime
				}
				itDns.MaxLifetime = val
			case "max_open_connections":
				if !c.NextArg() {
					return c.ArgErr()
				}
				var val int
				val, err = strconv.Atoi(c.Val())
				if err != nil {
					val = defaultMaxOpenConnections
				}
				itDns.MaxOpenConnections = val
			case "max_idle_connections":
				if !c.NextArg() {
					return c.ArgErr()
				}
				var val int
				val, err = strconv.Atoi(c.Val())
				if err != nil {
					val = defaultMaxIdleConnections
				}
				itDns.MaxIdleConnections = val
			case "zone_update_interval":
				if !c.NextArg() {
					return c.ArgErr()
				}
				var val time.Duration
				val, err = time.ParseDuration(c.Val())
				if err != nil {
					val = defaultZoneUpdateTime
				}
				itDns.zoneUpdateTime = val
			case "ttl":
				if !c.NextArg() {
					return c.ArgErr()
				}
				var val int
				val, err = strconv.Atoi(c.Val())
				if err != nil {
					val = defaultTtl
				}
				itDns.Ttl = uint32(val)
			default:
				if c.Val() != "}" {
					return c.Errf("unknown property '%s'", c.Val())
				}
			}

			if !c.Next() {
				break
			}
		}

	}

	return nil
}
